home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The 640 MEG Shareware Studio 2
/
The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO
/
clang
/
nn.zip
/
TERM.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-12-31
|
27KB
|
1,571 lines
/*
* terminal interface
*/
#include <signal.h>
#include <errno.h>
#include "config.h"
#include "term.h"
#include "keymap.h"
#ifdef RESIZING
#include <sys/ioctl.h> /* for TIOCGWINSZ */
int s_resized;
#endif
export char *term_name;
export int show_current_time = 1;
export int conf_dont_sleep = 0;
export int prompt_length;
export int terminal_speed;
export int slow_speed = 1200;
export int any_message = 0;
export int flow_control = 1;
export int use_visible_bell = 1; /* if supported by terminal */
export unsigned char help_key = '?';
export unsigned char comp1_key = SP;
export unsigned char comp2_key = TAB;
export unsigned char erase_key, kill_key;
export unsigned char delword_key = CONTROL_('W');
static char bell_str[256] = "\007";
#ifdef USE_TERMINFO
#include <curses.h>
#ifndef auto_left_margin
#include <term.h>
#endif
#define HAS_CAP(str) (str && *str)
extern char *tgoto(); /* some systems don't have this in term.h */
#else
#define USE_TERMCAP
char *tgoto();
char PC;
char *BC, *UP;
short ospeed;
static char XBC[64], XUP[64];
static char enter_ca_mode[64], exit_ca_mode[64];
static char cursor_home[64];
static char cursor_address[64];
static char clear_screen[64];
static char clr_eol[64];
static char clr_eos[64];
static char enter_standout_mode[64], exit_standout_mode[64];
static char enter_underline_mode[64], exit_underline_mode[64];
static char key_down[64], key_up[64], key_right[64], key_left[64];
int magic_cookie_glitch; /* magic cookie size */
#define putp(str) tputs(str, 0, outc)
#define HAS_CAP(str) (*str)
static outc(c)
{
putchar(c);
}
#endif /* USE_TERMCAP */
int Lines, Columns; /* screen size */
int cookie_size; /* size of magic cookie */
int two_cookies; /* space needed to enter&exit standout mode */
int STANDOUT; /* terminal got standout mode */
int WRAP; /* terminal got automatic margins */
#ifdef HAVE_TERMIO
#define KEY_BURST 50 /* read bursts of 50 chars (or timeout after 100 ms) */
#ifdef USE_TERMCAP
#include <termio.h>
#endif
#undef CBREAK
static struct termio norm_tty, raw_tty;
#define IntrC norm_tty.c_cc[VINTR]
#define EraseC norm_tty.c_cc[VERASE]
#define KillC norm_tty.c_cc[VKILL]
#define SuspC CONTROL_('Z') /* norm_tty.c_cc[SWTCH] */
#else /* V7/BSD TTY DRIVER */
#include <sgtty.h>
static struct sgttyb norm_tty, raw_tty;
static struct tchars norm_chars;
#define IntrC norm_chars.t_intrc
#define EraseC norm_tty.sg_erase
#define KillC norm_tty.sg_kill
#ifdef TIOCGLTC
static struct ltchars spec_chars;
#define SuspC spec_chars.t_suspc
#else
#define SuspC CONTROL_('Z')
#endif
#endif
#ifdef USE_TERMCAP
opt_cap(cap, buf)
char *cap, *buf;
{
char *tgetstr();
*buf = NUL;
return tgetstr(cap, &buf) != NULL;
}
get_cap(cap, buf)
char *cap, *buf;
{
if (!opt_cap(cap, buf))
user_error("TERMCAP entry for %s has no '%s' capability",
term_name, cap);
}
#endif /* USE_TERMCAP */
static int multi_keys = 0;
static struct multi_key {
char *cur_key;
char *keys;
int code;
} multi_key_list[MULTI_KEYS];
enter_multi_key(code, keys)
int code;
char *keys;
{
register i;
/* lookup code to see if it is already defined... */
for (i = 0; i < multi_keys; i++)
if (multi_key_list[i].code == code)
goto replace_key;
i = multi_keys++;
/* now i points to matching or empty slot */
if (i >= MULTI_KEYS) {
/* should never happen */
log_entry('E', "too many multi keys");
return;
}
replace_key:
multi_key_list[i].keys = keys;
multi_key_list[i].code = code;
}
dump_multi_keys()
{
register i;
register char *cp;
extern char *key_name();
clrdisp();
pg_init(0, 1);
for (i = 0; i < multi_keys; i++) {
if (pg_next() < 0) break;
printf("%d\t%s\t", i, key_name(multi_key_list[i].code));
for (cp = multi_key_list[i].keys; *cp; cp++) {
putchar(SP);
fputs(key_name(*cp), stdout);
}
}
pg_end();
}
#ifdef RESIZING
sig_type catch_winch()
{
struct winsize winsize;
(void) signal(SIGWINCH, catch_winch);
if (ioctl(0, TIOCGWINSZ, &winsize) >= 0
&& (winsize.ws_row != Lines || winsize.ws_col != Columns)) {
Lines = winsize.ws_row;
Columns = winsize.ws_col;
s_redraw = 1;
s_resized = 1;
}
}
#endif /* RESIZING */
#ifdef SV_INTERRUPT
#ifdef NO_SIGINTERRUPT
static siginterrupt(signo, on)
{
struct sigvec sv;
sv.sv_handler = signal (signo, SIG_DFL);
sv.sv_mask = 0;
sv.sv_flags = on ? SV_INTERRUPT : 0;
sigvec (signo, &sv, 0);
}
#endif
#endif
init_term()
{
#ifdef USE_TERMCAP
char tbuf[1024];
#endif
if ((term_name = getenv("TERM")) == NULL)
user_error("No TERM variable in enviroment");
#ifdef HAVE_TERMIO
ioctl(0, TCGETA, &norm_tty);
#else
ioctl(0, TIOCGETP, &norm_tty);
#endif
#ifdef USE_TERMINFO
setupterm((char *)NULL, 1, (int *)NULL);
Columns = columns;
Lines = lines;
cookie_size = magic_cookie_glitch;
WRAP = auto_right_margin;
if (use_visible_bell && HAS_CAP(flash_screen))
strcpy(bell_str, flash_screen);
else if (HAS_CAP(bell))
strcpy(bell_str, bell);
if (! HAS_CAP(cursor_home))
cursor_home = copy_str(tgoto(cursor_address, 0, 0));
#else
if (tgetent(tbuf, term_name) <= 0)
user_error("Unknown terminal type: %s", term_name);
if (opt_cap("bc", XBC)) BC = XBC;
if (opt_cap("up", XUP)) UP = XUP;
opt_cap("pc", cursor_address); /* temp. usage */
PC = cursor_address[0];
get_cap("cm", cursor_address);
if (!opt_cap("ho", cursor_home))
strcpy(cursor_home, tgoto(cursor_address, 0, 0));
get_cap("cl", clear_screen);
get_cap("ce", clr_eol);
opt_cap("cd", clr_eos);
#ifdef RESIZING
{
struct winsize winsize;
if (ioctl(0, TIOCGWINSZ, &winsize) >= 0
&& winsize.ws_row != 0 && winsize.ws_col != 0) {
Lines = winsize.ws_row;
Columns = winsize.ws_col;
(void) signal(SIGWINCH, catch_winch);
#ifdef SV_INTERRUPT
siginterrupt(SIGWINCH, 1); /* make read from tty interruptable */
#endif /* SV_INTERRUPT */
}
}
if (Lines == 0 || Columns == 0) {
#endif /* RESIZING */
Lines = tgetnum("li");
Columns = tgetnum("co");
#ifdef RESIZING
}
#endif /* RESIZING */
opt_cap("so", enter_standout_mode);
opt_cap("se", exit_standout_mode);
opt_cap("us", enter_underline_mode);
opt_cap("ue", exit_underline_mode);
opt_cap("kd", key_down);
opt_cap("ku", key_up);
opt_cap("kr", key_right);
opt_cap("kl", key_left);
cookie_size = tgetnum("sg");
WRAP = tgetflag("am");
opt_cap("ti", enter_ca_mode);
opt_cap("te", exit_ca_mode);
if (!use_visible_bell || !opt_cap("vb", bell_str))
if (!opt_cap("bl", bell_str))
strcpy(bell_str, "\007");
#endif /* !USE_TERMINFO */
STANDOUT = HAS_CAP(enter_standout_mode);
if (STANDOUT) {
if (cookie_size < 0) cookie_size = 0;
two_cookies = 2 * cookie_size;
} else
cookie_size = two_cookies = 0;
raw_tty = norm_tty;
#ifdef HAVE_TERMIO
raw_tty.c_iflag &= ~(BRKINT|INLCR|ICRNL|IGNCR);
raw_tty.c_iflag |= IGNBRK|IGNPAR|ISTRIP;
raw_tty.c_oflag &= ~OPOST;
raw_tty.c_lflag &= ~(ISIG|ICANON|XCASE|ECHO|NOFLSH);
/* read a maximum of 10 characters in one burst; timeout in 1-200 ms */
raw_tty.c_cc[VEOF] = KEY_BURST;
raw_tty.c_cc[VEOL] = ((raw_tty.c_cflag & CBAUD) > B1200) ? 1 : 2;
set_term_speed((unsigned)(raw_tty.c_cflag & CBAUD));
#else
ioctl(0, TIOCGETC, &norm_chars);
#ifdef TIOCGLTC
ioctl(0, TIOCGLTC, &spec_chars);
#endif
ospeed = norm_tty.sg_ospeed;
set_term_speed((unsigned)ospeed);
raw_tty.sg_flags &= ~ECHO;
#ifdef CBREAK
#ifdef SV_INTERRUPT /* make read from tty interruptable */
siginterrupt(SIGTSTP, 1); /* this is necessary to redraw screen */
#endif
raw_tty.sg_flags |= CBREAK;
#else
raw_tty.sg_flags |= RAW;
#endif
#ifdef SV_INTERRUPT
siginterrupt(SIGALRM, 1); /* make read from tty interruptable */
#endif
#endif
if (HAS_CAP(key_down)) enter_multi_key(K_down_arrow, key_down);
if (HAS_CAP(key_up)) enter_multi_key(K_up_arrow, key_up);
if (HAS_CAP(key_right)) enter_multi_key(K_right_arrow, key_right);
if (HAS_CAP(key_left)) enter_multi_key(K_left_arrow, key_left);
erase_key = EraseC;
kill_key = KillC;
visual_on();
}
static unsigned sp_table[] = {
B9600, 960,
#ifdef B19200
B19200, 1920,
#else
#ifdef EXTA
EXTA, 1920,
#endif
#endif
#ifdef B38400
B38400, 3840,
#else
#ifdef EXTB
EXTB, 3840,
#endif
#endif
B1200, 120,
B2400, 240,
B4800, 480,
B300, 30,
0, 0
};
static set_term_speed(sp)
register unsigned long sp;
{
register unsigned *tp;
for (tp = sp_table; *tp; tp += 2)
if (*tp == sp) {
terminal_speed = tp[1];
return;
}
terminal_speed = 30;
}
home()
{
putp(cursor_home);
}
static int curxy_c = -1, curxy_l, savxy_c = -1, savxy_l;
save_xy()
{
savxy_c = curxy_c; savxy_l = curxy_l;
}
restore_xy()
{
if (savxy_c < 0) return;
gotoxy(savxy_c, savxy_l); fl;
}
gotoxy(c, l)
int c, l;
{
curxy_c = c; curxy_l = l;
putp(tgoto(cursor_address, c, l));
}
clrdisp()
{
#ifdef USE_TERMINFO
putp(clear_screen); /* tputs is broken on UNISYS I've been told */
#else
tputs(clear_screen, Lines, outc);
#endif
curxy_c = savxy_c = -1;
}
clrline()
{
putp(clr_eol);
fl;
}
clrpage(lineno)
register int lineno;
{
register int olineno= lineno;
if (HAS_CAP(clr_eos)) {
#ifdef USE_TERMINFO
putp(clr_eos);
#else
tputs(clr_eos, Lines - lineno, outc);
#endif
} else {
clrline();
lineno++;
for (; lineno < Lines; lineno++) {
gotoxy(0, lineno);
putp(clr_eol);
}
gotoxy(0, olineno);
fl;
}
}
static char so_buf[512], *so_p;
static int so_c, so_l, so_b, so_active = 0;
so_gotoxy(c, l, blank)
{
if (!STANDOUT && c >= 0) {
if (l >= 0) gotoxy(c, l);
return 0;
}
so_active++;
so_c = c;
so_l = l;
so_b = blank;
so_p = so_buf;
*so_p = NUL;
return 1; /* not really true if not standout & c < 0 */
}
/*VARARGS*/
so_printf(va_alist)
va_dcl
{
va_list ap;
va_start(ap);
so_vprintf(va_args1toN);
va_end(ap);
}
so_vprintf(va_tail)
va_tdcl
{
char *fmt;
fmt = va_arg1(char *);
if (!so_active) {
vprintf(fmt, va_args2toN);
return;
}
vsprintf(so_p, fmt, va_args2toN);
while (*so_p) so_p++;
}
so_end()
{
int len;
if (!so_active) return;
if (so_l >= 0) {
len = so_p - so_buf + two_cookies;
if (so_c < 0)
so_c = Columns - len - 2;
if (so_c < 0) so_c = 0;
if (len + so_c >= Columns) {
len = Columns - so_c - two_cookies;
so_buf[len] = NUL;
}
if (cookie_size) {
gotoxy(so_c + len - cookie_size, so_l);
putp(exit_standout_mode);
}
gotoxy(so_c, so_l);
}
if ((so_b & 1) && (!STANDOUT || !cookie_size)) putchar(SP);
if (STANDOUT) putp(enter_standout_mode);
fputs(so_buf, stdout);
if (STANDOUT) putp(exit_standout_mode);
if ((so_b & 2) && (!STANDOUT || !cookie_size)) putchar(SP);
so_active = 0;
}
/*VARARGS*/
so_printxy(va_alist)
va_dcl
{
va_list ap;
int k, l;
va_start(ap);
k = va_arg1(int);
l = va_arg2(int);
so_gotoxy(k, l, 0);
so_vprintf(va_args3toN);
so_end();
va_end(ap);
}
underline(on)
{
if (cookie_size) return 0;
if (! HAS_CAP(enter_underline_mode)) return 0;
putp(on ? enter_underline_mode : exit_underline_mode);
return 1;
}
highlight(on)
{
if (cookie_size) return 0;
if (! HAS_CAP(enter_standout_mode)) return 0;
putp(on ? enter_standout_mode : exit_standout_mode);
return 1;
}
static int is_visual = 0;
visual_on()
{
if (HAS_CAP(enter_ca_mode)) {
putp(enter_ca_mode);
is_visual = 1;
}
}
visual_off()
{
if (is_visual && HAS_CAP(exit_ca_mode)) putp(exit_ca_mode), fl;
is_visual = 0;
}
static int is_raw = 0;
static int must_set_raw = 1;
#ifndef CBREAK
raw()
{
if (!flow_control) {
if (!must_set_raw) return;
must_set_raw = 0;
}
if (is_raw) return;
#ifdef HAVE_TERMIO
ioctl(0, TCSETAF, &raw_tty);
#else
ioctl(0, TIOCSETP, &raw_tty);
#endif
is_raw++;
}
no_raw()
{
if (!flow_control) return 0;
if (!is_raw) return 0;
#ifdef HAVE_TERMIO
ioctl(0, TCSETAF, &norm_tty);
#else
ioctl(0, TIOCSETP, &norm_tty);
#endif
is_raw = 0;
return 1;
}
unset_raw()
{
int oflow = flow_control;
int was_raw;
flow_control = 1;
was_raw = no_raw();
flow_control = oflow;
if (!flow_control)
must_set_raw = 1;
return was_raw;
}
#else /* not CBREAK */
raw()
{
if (is_raw == 1)
return;
is_raw = 1;
ioctl(0, TIOCSETP, &raw_tty); /* no TERMIO ??? */
}
no_raw()
{
return 0;
}
unset_raw()
{
if (is_raw == 0)
return 0;
ioctl(0, TIOCSETP, &norm_tty); /* no TERMIO ??? */
is_raw = 0;
return 1;
}
#endif /* CBREAK */
static int do_flush_input = 0;
flush_input()
{
#ifdef HAVE_TERMIO
ioctl(0, TCFLSH, 0);
do_flush_input = 1;
#else
#ifdef FREAD
int arg = FREAD;
ioctl(0, TIOCFLUSH, &arg);
#else
ioctl(0, TIOCFLUSH, 0);
#endif
#endif
}
int enable_stop = 1;
#ifndef KEY_BURST
static int alarm_on = 0;
static mk_timeout()
{
alarm_on = 0;
}
#endif
static int do_macro_processing = 1;
get_c()
{
unsigned char c;
int any_multi, key_cnt, mc;
register struct multi_key *mk;
register int i;
#ifdef KEY_BURST
static char cbuf[KEY_BURST], *cp;
static int n = 0;
if (do_flush_input) {
do_flush_input = 0;
n = 0;
}
#else
int n;
unsigned char first_key;
#endif
next_key:
if (s_hangup)
return K_interrupt;
#ifdef RESIZING
if (s_resized) {
s_resized = 0;
return GETC_COMMAND | K_REDRAW;
}
#endif
if (do_macro_processing)
switch (m_getc(&mc)) {
case 0:
break;
case 1:
return mc;
case 2:
return K_interrupt;
}
for (i = multi_keys, mk = multi_key_list; --i >= 0; mk++)
mk->cur_key = mk->keys;
key_cnt = 0;
#ifdef KEY_BURST
if (n <= 0) {
n = read(0, cbuf, KEY_BURST);
if (n < 0 && errno != EINTR) s_hangup++;
if (n <= 0) return K_interrupt;
cp = cbuf;
}
while (--n >= 0) {
c = *cp++;
#else
while ((n = read(0, &c, 1)) > 0) {
c &= 0177; /* done by ISTRIP on USG systems */
#endif
if (c == CONTROL_('Q') || c == CONTROL_('S'))
continue;
any_multi = 0;
for (i = multi_keys, mk = multi_key_list; --i >= 0; mk++)
if (mk->cur_key) {
if (*(mk->cur_key)++ == c) {
if (*(mk->cur_key) == NUL) {
c = mk->code;
goto got_char;
}
any_multi++;
} else
mk->cur_key = NULL;
}
if (any_multi) {
#ifndef KEY_BURST
if (key_cnt == 0) {
first_key = c;
alarm_on = 1;
signal(SIGALRM, mk_timeout);
MICRO_ALARM();
}
#endif
key_cnt++;
continue;
}
if (key_cnt == 0)
goto got_char;
ding();
flush_input();
goto next_key;
}
#ifdef CBREAK
if (s_redraw) {
s_redraw = 0;
return GETC_COMMAND | K_REDRAW;
}
#endif
#ifndef KEY_BURST
if (n < 0) {
if (errno != EINTR) s_hangup++;
return K_interrupt;
}
#endif
#ifdef RESIZING
if (s_resized) {
s_resized = 0;
return GETC_COMMAND | K_REDRAW;
}
#endif
#ifndef KEY_BURST
if (n < 0 && key_cnt)
c = first_key;
#endif
got_char:
#ifndef KEY_BURST
if (alarm_on) {
alarm(0);
alarm_on = 0;
}
#endif
c = global_key_map[c];
#ifndef CBREAK
if (c == SuspC) {
if (!enable_stop) goto next_key;
if (suspend_nn())
return GETC_COMMAND | K_REDRAW;
else
goto next_key;
}
if (c == IntrC) c = K_interrupt;
#endif
return c;
}
/*
* read string with completion, pre-filling, and break on first char
*
* dflt is a string that will be use as default value if the
* space bar is hit as the first character.
*
* prefill pre-fill the buffer with .... and print it
*
* break_chars return immediately if one of these characters
* is entered as the first character.
*
* completion is a function that will fill the buffer with a value
* see the group_completion and file_completion routines
* for examples.
*/
char *get_s(dflt, prefill, break_chars, completion)
char *dflt, *prefill, *break_chars;
int (*completion)();
{
static char buf[GET_S_BUFFER];
register char *cp;
register int i, c, lastc;
char *ret_val = buf;
int comp_used, comp_len;
int ostop, max, did_help;
int hit_count;
switch (m_gets(buf)) {
case 0:
break;
case 1:
return buf;
case 2:
return NULL;
}
ostop = enable_stop;
enable_stop = 0;
do_macro_processing = 0;
hit_count = 0;
max = Columns - prompt_length;
if (max >= FILENAME) max = FILENAME-1;
i = comp_len = comp_used = did_help = 0;
if (prefill && prefill[0]) {
while (c = *prefill++) {
if (i == max) break;
putchar(c);
buf[i] = c;
i++;
}
fl;
}
if (dflt && *dflt == NUL)
dflt = NULL;
if (break_chars && *break_chars == NUL)
break_chars = NULL;
c = NUL;
for(;;) {
lastc = c;
c = get_c();
if (c & GETC_COMMAND) continue;
kill_prefill_hack:
hit_count++;
if (i == 0) {
if (c == comp1_key && dflt) {
while ((c = *dflt++) != NUL && i < max) {
putchar(c);
buf[i] = c;
i++;
}
fl;
dflt = NULL;
continue;
}
if (cp = break_chars) {
while (*cp)
if (*cp++ == c) {
buf[0] = c;
buf[1] = NUL;
goto out;
}
}
}
if (completion != NO_COMPLETION) {
if (comp_used && c == erase_key) {
(*completion)(buf, -1);
if (did_help) { clrmsg(i); did_help = 0; }
if (comp_len) {
i -= comp_len;
while (--comp_len >= 0) putchar(BS);
clrline();
}
comp_len = comp_used = 0;
if (lastc == help_key) goto no_completion;
continue;
}
if (c == comp1_key || c == comp2_key || c == help_key) {
if (!comp_used || c == comp2_key ||
(c == help_key && lastc != c)) {
buf[i] = NUL;
if ((comp_used = (*completion)(buf, i)) == 0) {
ding();
continue;
}
if (comp_used < 0) {
comp_used = 0;
goto no_completion;
}
comp_len = 0;
}
if (c == help_key) {
if ((*completion)((char *)NULL, 1)) {
gotoxy(prompt_length+i, prompt_line); fl;
did_help = 1;
}
continue;
}
if (comp_len) {
i -= comp_len;
while (--comp_len >= 0) putchar(BS);
clrline();
comp_len = 0;
}
switch ( (*completion)((char *)NULL, 0) ) {
case 0: /* no possible completion */
comp_used = 0;
ding();
continue;
case 2: /* whole new alternative */
while (--i >= 0) putchar(BS);
clrline();
/* fall thru */
case 1: /* completion */
comp_len = i;
while (c = buf[i]) {
if (i == max) break;
putchar(c);
i++;
}
fl;
comp_len = i - comp_len;
continue;
}
}
if (comp_used) {
(*completion)(buf, -1);
if (did_help) clrmsg(i);
comp_len = comp_used = 0;
}
}
no_completion:
if (c == CR || c == NL) {
buf[i] = NUL;
break;
}
if (c == erase_key) {
if (i <= 0) continue;
i--;
putchar(BS);
putchar(' ');
putchar(BS);
fl;
continue;
}
if (c == delword_key) {
if (i <= 0) continue;
buf[i-1] = 'X';
while (i > 0 && isalnum(buf[i-1])) { putchar(BS); i--; }
clrline();
continue;
}
if (c == kill_key) {
while (i > 0) { putchar(BS); i--; }
clrline();
if (hit_count == 1 && dflt) {
c = comp1_key;
goto kill_prefill_hack;
}
continue;
}
if (c == K_interrupt) {
ret_val = NULL;
break;
}
if (!isascii(c) || !isprint(c)) continue;
if (i == max) continue;
if (i > 0 && buf[i-1] == '/' && (c == '/' || c == '+')) {
while (i > 0) { putchar(BS); i--; }
clrline();
}
putchar(c);
fl;
buf[i] = c;
i++;
}
out:
enable_stop = ostop;
do_macro_processing = 1;
return ret_val;
}
export int list_offset = 0;
list_completion(str)
char *str;
{
static int cols, line;
if (str == NULL) {
cols = Columns;
line = prompt_line + 1;
gotoxy(0, line);
clrpage(line);
return 1;
}
str += list_offset;
for (;;) {
cols -= strlen(str);
if (cols >= 0) {
printf("%s%s", str, cols > 0 ? " " : "");
cols--;
return 1;
}
if (line >= Lines - 1) return 0;
line++;
cols = Columns;
gotoxy(0, line);
if (line == Lines - 1) cols--;
}
}
yes(must_answer)
int must_answer;
{
int c, help = 1, in_macro = 0;
switch (m_yes()) {
case 0:
break;
case 1:
return 0;
case 2:
return 1;
case 3:
do_macro_processing = 0;
in_macro++;
break;
}
for (;;) {
if (!is_raw) {
raw();
c = get_c();
unset_raw();
} else
c = get_c();
if (c == 'y' || c == 'Y') {
c = 1;
break;
}
if (must_answer == 0 && (c == SP || c == CR || c == NL)) break;
if (c == 'n' || c == 'N') {
c = 0;
break;
}
if (c == K_interrupt) {
c = -1;
break;
}
if (help) {
fputs(" y=YES n=NO", stdout);
prompt_length += 11;
help = 0;
}
}
if (in_macro) {
if (c < 0) m_break();
do_macro_processing = 1;
}
return c;
}
ding()
{
putp(bell_str);
fl;
}
display_file(name, modes)
char *name;
int modes;
{
FILE *f;
register c, stand_on;
int linecnt, headln_cnt, hdline, no_conf;
char headline[128];
headline[0] = 0;
hdline = 0;
no_conf = 0;
headln_cnt = -1;
if (modes & CLEAR_DISPLAY) {
gotoxy(0,0);
clrdisp();
}
linecnt = Lines - 1;
chain:
f = open_file(relative(lib_directory, name), OPEN_READ);
if (f == NULL)
printf("\r\n\nFile %s is not available\n\n", name);
else {
stand_on = 0;
while ((c = getc(f)) != EOF) {
#ifdef HAVE_JOBCONTROL
if (s_redraw) {
no_conf = 1;
break;
}
#endif
no_conf = 0;
if (c == '\1') {
if (STANDOUT) {
putp(stand_on ? exit_standout_mode : enter_standout_mode);
stand_on = !stand_on;
}
continue;
}
if (c == '\2') {
headln_cnt = 0;
continue;
}
if (c == '\3') {
headln_cnt = 0;
while ((c = getc(f)) != EOF && c != NL)
headline[headln_cnt++] = c;
headline[headln_cnt++] = NUL;
name = headline;
fclose(f);
goto chain;
}
if (headln_cnt >= 0)
headline[headln_cnt++] = c;
if (hdline) {
puts(headline);
putchar(CR);
hdline = 0;
linecnt--;
}
putchar(c);
if (c == NL) {
putchar(CR);
if (headln_cnt >= 0) {
headline[--headln_cnt] = 0;
headln_cnt = -1;
}
if (--linecnt == 0) {
no_conf = 1;
if (any_key(0) == K_interrupt)
break;
linecnt = Lines - 1;
if (modes & CLEAR_DISPLAY) {
gotoxy(0,0);
clrdisp();
}
hdline = headline[0];
}
}
}
if (stand_on) putp(exit_standout_mode);
fclose(f);
}
prompt_line = Lines-1; /* move prompt to last line */
if (!no_conf && (modes & CONFIRMATION))
any_key(prompt_line);
}
/*VARARGS*/
user_error(va_alist)
va_dcl
{
char *fmt;
va_list ap;
unset_raw();
clrdisp();
fl;
va_start(ap);
fmt = va_arg1(char *);
vprintf(fmt, va_args2toN);
putchar(NL);
va_end(ap);
nn_exit(1);
}
/*VARARGS*/
msg(va_alist)
va_dcl
{
va_list ap;
va_start(ap);
vmsg(va_args1toN);
va_end(ap);
}
vmsg(va_tail)
va_tdcl
{
static char errmsg[512] = "";
char *fmt;
fmt = va_arg1(char *);
if (fmt) vsprintf(errmsg, fmt, va_args2toN);
gotoxy(0, Lines-1);
fputs(errmsg, stdout);
clrline();
any_message = 1;
gotoxy(prompt_length, prompt_line);
fl;
}
clrmsg(col)
int col;
{
gotoxy(0, prompt_line + 1);
clrpage(prompt_line + 1);
if (col >= 0)
gotoxy(prompt_length + col, prompt_line);
fl;
any_message = 0;
}
/*VARARGS*/
prompt(va_alist)
va_dcl
{
register char *cp;
int stand_on;
char *fmt;
static char cur_p[FILENAME];
static char saved_p[FILENAME];
va_list ap;
va_start(ap);
fmt = va_arg1(char *);
if (fmt == P_VERSION) {
gotoxy(0, prompt_line + 1);
print_version("Release %R.%V, Patch Level %P, Compilation %U ");
clrline();
any_message++;
if (prompt_line >= 0)
gotoxy(prompt_length, prompt_line);
return;
}
if (fmt == P_SAVE) {
strcpy(saved_p, cur_p);
return;
}
if (fmt == P_RESTORE)
strcpy(cur_p, saved_p);
if (prompt_line >= 0)
gotoxy(0, prompt_line);
if (fmt == P_MOVE) {
clrline();
return;
}
if (fmt != P_REDRAW && fmt != P_RESTORE)
vsprintf(cur_p, fmt, va_args2toN);
putchar(CR);
for (cp = cur_p, stand_on = 0, prompt_length = 0; *cp; cp++) {
if (*cp == '\1') {
if (cp[1] != '\1') {
if (STANDOUT) {
putp(stand_on ? exit_standout_mode : enter_standout_mode);
stand_on = !stand_on;
prompt_length += cookie_size;
}
continue;
}
cp++;
} else
if (*cp == '\2') {
time_t t;
char *timestr;
#ifdef STATISTICS
tick_usage(&t, (time_t *)NULL);
#endif
if (show_current_time) {
#ifndef STATISTICS
time(&t);
#endif
timestr = ctime(&t) + 11;
timestr[5] = NUL;
printf("-- %s ", timestr);
prompt_length += 9;
}
if (unread_mail(t)) {
printf("Mail ");
prompt_length += 5;
}
continue;
}
putchar(*cp);
prompt_length ++;
}
if (stand_on) {
putp(exit_standout_mode);
prompt_length += cookie_size;
}
clrline();
if (fmt == P_RESTORE)
restore_xy();
else
curxy_c = -1;
}
any_key(line)
int line;
{
int was_raw, c, dmp;
was_raw = is_raw;
if (!is_raw) raw();
if (line == 0)
line = -1;
else
if (line < 0)
line = Lines + line;
if (line != 10000)
so_printxy(0, line, "Hit any key to continue");
clrline();
dmp = do_macro_processing;
do_macro_processing = 0;
c = get_c();
do_macro_processing = dmp;
if (!was_raw) unset_raw();
return c;
}
static pg_fline, pg_width, pg_maxw, pg_line, pg_col, pg_quit;
pg_init(first_line, cols)
int first_line, cols;
{
pg_fline = first_line;
pg_line = pg_fline - 1;
pg_quit = pg_col = 0;
pg_width = Columns / cols;
pg_maxw = pg_width * (cols - 1);
}
pg_scroll(n)
int n;
{
pg_line += n;
if (pg_line >= (Lines - 1)) {
pg_line = 0;
return any_key(0) == K_interrupt;
}
return 0;
}
pg_next()
{
int c;
pg_line++;
if (pg_line < Lines) {
gotoxy(pg_col, pg_line);
if (pg_line == Lines - 1 && pg_col == pg_maxw) {
c = any_key(0);
gotoxy(0, pg_fline);
clrpage(pg_fline);
pg_col = 0;
pg_line = pg_fline;
if (c == K_interrupt) {
pg_quit = 1;
return -1;
}
return 1;
}
} else {
pg_line = pg_fline;
pg_col += pg_width;
gotoxy(pg_col, pg_line);
}
return 0;
}
pg_indent(pos)
int pos;
{
gotoxy(pg_col + pos, pg_line);
}
pg_end()
{
if (pg_quit == 0 && pg_next() == 0)
any_key(0);
}
user_delay(ticks)
int ticks;
{
if (ticks <= 0 || conf_dont_sleep) {
printf(" <>");
any_key(10000);
} else {
fl;
sleep(ticks);
}
}